package top.sqdpt.third.strategy.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import top.sqdpt.third.config.WeatherProperties;
import top.sqdpt.third.entity.dto.*;
import top.sqdpt.third.enums.WeatherQueryType;
import top.sqdpt.third.enums.WeatherType;
import top.sqdpt.third.strategy.AbstractWeatherStrategy;
import top.sqdpt.third.utils.HttpUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 和风天气处理类
 * 实现和风天气API的调用
 */
@Slf4j
@Component
public class HeFengWeatherHandler extends AbstractWeatherStrategy {

    private static final String SUCCESS_CODE = "200";
    private static final String LOCATION_KEY = "location";
    private static final String DAILY_KEY = "daily";
    private static final String NOW_KEY = "now";
    private static final String CODE_KEY = "code";
    private static final String ID_KEY = "id";

    public HeFengWeatherHandler(WeatherProperties properties) {
        super(properties);
    }


    @Override
    public WeatherType getWeatherType() {
        return WeatherType.HE_FENG;
    }

    @Override
    public List<WeatherResponseDTO> queryWeather(WeatherRequestDTO requestDTO) {
        WeatherQueryType weatherQueryType = requestDTO.getWeatherQueryType();
        return switch (weatherQueryType) {
            case REAL_TIME -> {
                WeatherResponseDTO weatherResponseDTO = queryWeatherNow(requestDTO);
                yield List.of(weatherResponseDTO);
            }
            case THREE_DAYS, SEVEN_DAYS, TEN_DAYS, FIFTEEN_DAYS -> queryWeatherForecast(requestDTO);
            default -> throw new IllegalArgumentException("不支持的查询类型");
        };
    }

    @Override
    public List<WeatherResponseDTO> queryWeatherForecast(WeatherRequestDTO requestDTO) {
        String forecastUrl = buildForecastUrl(requestDTO);
        Map<String, Object> params = new HashMap<>();
        params.put(LOCATION_KEY, getCityCode(requestDTO.getAddress(), requestDTO.getCity()));
        String result = HttpUtil.getInstance().get(forecastUrl, params);

        // 解析 JSON 数据
        JSONObject jsonObject = JSON.parseObject(result);
        if (!SUCCESS_CODE.equals(jsonObject.getString(CODE_KEY))) {
            throw new RuntimeException("天气预报查询失败，返回码：" + jsonObject.getString(CODE_KEY));
        }

        // 提取 daily 数据
        JSONArray dailyArray = jsonObject.getJSONArray(DAILY_KEY);
        if (dailyArray == null || dailyArray.isEmpty()) {
            throw new RuntimeException("天气预报数据为空");
        }
        // 将 daily 数据转换为 List<WeatherResponseDTO>
        return dailyArray.stream()
                .map(item -> {
                    JSONObject dailyItem = (JSONObject) item;
                    WeatherResponseDTO dto = new WeatherResponseDTO();
                    dto.setDataTime(dailyItem.getString("fxDate")); // 日期
                    // 取白天的最高温度
                    dto.setTempMax(dailyItem.getString("tempMax")); // 最高温度

                    // 取白天的最低温度
                    dto.setTempMin(dailyItem.getString("tempMin")); // 最低温度

                    // 取白天的天气描述
                    dto.setText(dailyItem.getString("textDay")); // 白天天气描述

                    // 取白天的湿度
                    dto.setHumidity(dailyItem.getString("humidity")); // 湿度

                    // 取白天的风向
                    dto.setWindDirection(dailyItem.getString("windDirDay")); // 白天风向

                    // 取白天的风速
                    dto.setWindPower(dailyItem.getString("windSpeedDay")); // 白天风速

                    // 取白天的日出时间
                    dto.setSunrise(dailyItem.getString("sunrise"));

                    // 取白天的日落时间
                    dto.setSunset(dailyItem.getString("sunset"));
                    return dto;
                })
                .toList();
    }

    @Override
    public WeatherResponseDTO queryWeatherNow(WeatherRequestDTO requestDTO) {
        String nowUrl = buildNowUrl();
        Map<String, Object> params = new HashMap<>();
        params.put(LOCATION_KEY, getCityCode(requestDTO.getAddress(), requestDTO.getCity()));
        String result = HttpUtil.getInstance().get(nowUrl, params);
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject.getString(CODE_KEY).equals(SUCCESS_CODE)) {
            JSONObject now = jsonObject.getJSONObject(NOW_KEY);
            WeatherResponseDTO weatherResponseDTO = new WeatherResponseDTO();
            weatherResponseDTO.setDataTime(now.getString("fxTime"));
            weatherResponseDTO.setTemperature(now.getString("temp"));
            weatherResponseDTO.setFeelTemperature(now.getString("feelsLike"));
            weatherResponseDTO.setText(now.getString("text"));
            weatherResponseDTO.setHumidity(now.getString("humidity"));
            weatherResponseDTO.setWindDirection(now.getString("windDir"));
            weatherResponseDTO.setWindPower(now.getString("windScale"));
            weatherResponseDTO.setPrecip(now.getString("precip"));
            weatherResponseDTO.setView(now.getString("pressure"));
            weatherResponseDTO.setSunrise(now.getString("sunrise"));
            weatherResponseDTO.setSunset(now.getString("sunset"));
            weatherResponseDTO.setTempMax(now.getString("tempMax"));
            weatherResponseDTO.setTempMin(now.getString("tempMin"));
            return weatherResponseDTO;
        }
        throw new RuntimeException("获取天气信息失败");
    }

    @Override
    public String getCityCode(String address, String city) {
        String cityCodeUrl = getConfig().getCityCodeUrl();
        Map<String, Object> params = new HashMap<>();
        params.put(LOCATION_KEY, city);
        String result = HttpUtil.getInstance().get(cityCodeUrl, params);
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject.getString(CODE_KEY).equals(SUCCESS_CODE)) {
            JSONArray locations = JSON.parseArray(LOCATION_KEY);
            return locations.getJSONObject(0).getString(ID_KEY);
        }
        throw new RuntimeException("获取城市编码失败");
    }

    @Override
    protected String buildForecastUrl(WeatherRequestDTO requestDTO) {
        String forecastUrl = super.buildForecastUrl(null);
        forecastUrl = switch (requestDTO.getWeatherQueryType()) {
            case THREE_DAYS -> forecastUrl + "/3d";
            case SEVEN_DAYS -> forecastUrl + "/7d";
            case TEN_DAYS -> forecastUrl + "/10d";
            case FIFTEEN_DAYS -> forecastUrl + "/15d";
            case THIRTY_DAYS -> forecastUrl + "/30d";
            default -> throw new IllegalArgumentException("不支持的查询类型");
        };
        return forecastUrl;
    }
}
